#ifndef CONNECTIONPOOL_H
#define CONNECTIONPOOL_H
#include <mutex>
#include <condition_variable>
#include <mysql/jdbc.h>
#include<util.h>


class ConnectionPool {
public:
    std::vector<sql::Connection*> connections;
    std::mutex mtx;
    std::condition_variable cv;

public:
    //mysql连接初始化
    sql::Connection * initConnection(){
        sql::mysql::MySQL_Driver *driver;
        sql::Connection *con;
        try {
            driver = sql::mysql::get_mysql_driver_instance();
            con = driver->connect(std::string(getConfigChar("datasource:url")),
                                  std::string(getConfigChar("datasource:username")),
                                  std::string(getConfigChar("datasource:password")));
            con->setSchema(std::string(getConfigChar("datasource:dbname")));

            return con;
        } catch (sql::SQLException &e) {
            delete con;
            std::cerr << "SQLException: " << e.what() << std::endl;
            std::cout<<"请检查配置信息"<<std::endl;
        }
        return NULL;
    }


    ConnectionPool() {
        for (int i = 0; i < getConfigInt("connectionpool:max_con"); ++i) {
            sql::Connection* con = initConnection();
            if (con != nullptr) {
                connections.push_back(con);
            }
        }
        std::cout<<"db连接池初始化结束！"<<std::endl;
    }


    sql::Connection* getConnection() {
        std::unique_lock<std::mutex> lock(mtx);
        while (connections.empty()) {
            cv.wait(lock);
        }
        sql::Connection* con = connections.back();
        connections.pop_back();

        return con;
    }

    void releaseConnection(sql::Connection* con) {
        std::lock_guard<std::mutex> lock(mtx);
        connections.push_back(con);
        cv.notify_one();
    }
};
#endif // CONNECTIONPOOL_H
